#include "FTPServer.h"

FTPServer::FTPServer(const std::string& ip, int port)
	: server_(new TcpServer(ip, port)),
	started_(false)
{
	server_->setConnectionCallback(std::bind(&FTPServer::onConnectionEstablished, this, std::placeholders::_1));
	server_->setWriteCompleteCallback(std::bind(&FTPServer::onWriteComplete, this, std::placeholders::_1));
	server_->setMessageCallback(std::bind(&FTPServer::onMessage, this, std::placeholders::_1, std::placeholders::_2));
	server_->setCloseCallback(std::bind(&FTPServer::onCloseConnection, this, std::placeholders::_1));
}

void FTPServer::onMessage(std::shared_ptr<TcpConnection> conn, Buffer& inBuffer)
{
	// 提取出buffer中第一个字节到最后一个\r\n结束符，组成的string
	std::string msg(inBuffer.data(), inBuffer.data() + inBuffer.readableSize());
	size_t lastCRLT = msg.find_last_of("\r\n");
	if (lastCRLT == std::string::npos) {
		return;
	}
	msg = msg.substr(0, lastCRLT + 1);
    inBuffer.retrieve(msg.length());
	//std::cout << conn->name() << " ->" << msg;
	//conn->send(msg.data(), msg.length());
	SessionPtr pSession;
	{
		std::lock_guard<std::mutex> lock(sessionMapLock_);
		auto sessionPair = sessionMap_.find(conn->name());
		assert(sessionPair != sessionMap_.end());
		pSession = sessionPair->second;
	}
	if (!pSession) {
		LOG_ERROR << conn->name() << "'s pSession is nullptr";
		return;
	}
	pSession->parseCmd(msg);
}

void FTPServer::onWriteComplete(std::shared_ptr<TcpConnection> conn)
{
	std::cout << conn->name() << " write complete!" << std::endl;
	std::lock_guard<std::mutex> lock(sessionMapLock_);
	auto sessionPair = sessionMap_.find(conn->name());
	assert(sessionPair != sessionMap_.end());
	SessionPtr pSession = sessionPair->second;
}

void FTPServer::onConnectionEstablished(std::shared_ptr<TcpConnection> conn)
{
	conn->setTimeout(timeval{1200,0});
	std::shared_ptr<FTPSession> session = std::make_shared<FTPSession>(conn);
	std::lock_guard<std::mutex> lock(sessionMapLock_);
	sessionMap_.emplace( std::make_pair(session->name(),session));
}

void FTPServer::onCloseConnection(std::shared_ptr<TcpConnection> conn)
{
	std::cout << conn->name() << " close connection!" << std::endl;
	std::lock_guard<std::mutex> lock(sessionMapLock_);
	sessionMap_.erase(conn->name());
}

void FTPServer::start()
{
	server_->Start(4);
}
